package com.crs.service.impl;

import com.crs.dto.UserLoginDTO;
import com.crs.dto.UserRegisterDTO;
import com.crs.entity.User;
import com.crs.exception.BusinessException;
import com.crs.mapper.UserMapper;
import com.crs.service.UserService;
import com.crs.utils.AliOssUtil;
import com.crs.utils.JwtUtil;
import com.crs.vo.UserLoginVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private AliOssUtil aliOssUtil;

    public static final Long TOKEN_TIME=7200000L;
    /**
     * 用户登录
     * @param userLoginDTO
     * @return
     */
    @Override
    public UserLoginVo login(UserLoginDTO userLoginDTO) {
        String username = userLoginDTO.getUsername();
        String password = userLoginDTO.getPassword();
        User user = userMapper.findByUsername(username);
        if(user == null){
            throw new BusinessException("用户不存在，请先注册");
        }
        if(!passwordEncoder.matches(password,user.getPassword())){
            throw new BusinessException("用户密码错误");
        }
        //生成token放入redis
        Map<String, Object> claims = new HashMap<>();
        claims.put("userId",user.getId());
        String token = JwtUtil.createJWT(claims);
        stringRedisTemplate.opsForValue().set("user:token:"+user.getId(),token,TOKEN_TIME, TimeUnit.SECONDS);

        //设置token过期时间
        String tokenExpireTime = String.valueOf(LocalDateTime.now().plusSeconds(TOKEN_TIME));

        //封装vo
        UserLoginVo userLoginVo = UserLoginVo.builder()
                .userId(user.getId())
                .username(user.getUsername())
                .phone(user.getPhone())
                .email(user.getEmail())
                .token(token)
                .tokenExpireTime(tokenExpireTime)
                .build();
        return userLoginVo;
    }

    /**
     * 用户注册
     * @param userRegisterDTO
     * @param avatar
     */
    @Override
    @Transactional
    public void register(UserRegisterDTO userRegisterDTO, MultipartFile avatar) throws IOException {

        // 1.检查用户名是否已存在
        String username = userRegisterDTO.getUsername();
        if (userMapper.findByUsername(username) != null) {
            throw new BusinessException("用户名已存在");
        }

        // 2.检查手机号是否已存在
        String phone = userRegisterDTO.getPhone();
        Boolean phoneExists = userMapper.existsByPhone(phone);
        if (phoneExists != null && phoneExists) {
            throw new BusinessException("手机号已被注册");
        }

        // 3.检查邮箱是否已存在
        String email = userRegisterDTO.getEmail();
        if (userMapper.existsByEmail(email) != 0) {
            throw new BusinessException("邮箱已被注册");
        }

        // 4.对密码进行加密
        String password = userRegisterDTO.getPassword();
        String encryptedPassword = passwordEncoder.encode(password);

        String filepath = null;
        // 先上传头像到OSS
        try{
            String originFilename = avatar.getOriginalFilename();
            String extension = originFilename.substring(originFilename.lastIndexOf("."));
            String objectName = UUID.randomUUID().toString() + extension;
            filepath = aliOssUtil.upload(avatar.getBytes(),objectName);
        }catch (IOException e){
            log.error("文件上传失败",e);
            throw new BusinessException("头像上传失败");
        }
        
        // 设置头像URL
        userRegisterDTO.setAvatar(filepath);
        // 5.构建用户对象
        User user = User.builder()
                .username(username)
                .password(encryptedPassword)
                .phone(phone)
                .email(email)
                .avatar(userRegisterDTO.getAvatar())
                .createTime(LocalDateTime.now())
                .updateTime(LocalDateTime.now())
                .build();

        // 6.保存用户
        userMapper.insert(user);
    }

    /**
     * 管理员解除或封禁用户
     * @param status
     * @param userId
     */
    @Override
    public void releaseOrBan(Integer status, Long userId) {
        User user = userMapper.findById(userId);
        if(user == null){
            throw new BusinessException("该用户不存在");
        }
        if(user.getStatus() == status){
            throw new BusinessException("用户已经是此状态了");
        }
        //解除或封禁用户
        userMapper.updateStatus(status,userId);
    }
}
